package com.calvin.study.multithread.safe.pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.calvin.study.utils.ThreadUtil;

/**
 * 该示例演示：使用多线程中的知识（锁和通知）实现生产者和消费者的案例。
 */
public class PcDemo01 {

	//生产或消费的标识
	private static int pc = 0;

	private static Lock pcLock = new ReentrantLock();
	private static Condition pcCon = pcLock.newCondition();
	
	public static void main(String[] args) {
		pc();
	}

	public static void pc() {
		for (int i = 0, len = 5; i < len; i++) {
			new Thread(() -> {
				pcLock.lock();
				try {
					while (pc != 0) {
						pcCon.await();
					}
					pc++;
					System.out.println(ThreadUtil.getCurThreadName() + pc);
					ThreadUtil.sleepSeconds(1);
					pcCon.signalAll();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					pcLock.unlock();
				}
			}, "我是生产者").start();

			new Thread(() -> {
				pcLock.lock();
				try {
					while (pc == 0) {
						// 通知消费者
						pcCon.await();
					}
					pc--;
					System.out.println(ThreadUtil.getCurThreadName() + pc);
					ThreadUtil.sleepSeconds(1);
					pcCon.signalAll();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					pcLock.unlock();
				}
			}, "我是消费者").start();
		}
	}

}
